package com.xbongbong.workflow.service.strategy.data.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.enums.TaskTypeEnum;
import com.xbongbong.paas.pojo.dto.SaasFormSaveDTO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.FormDataUtil;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.formdata.pojo.SaasNeedRedundantAttrPojo;
import com.xbongbong.pro.workflow.enums.WorkflowOperateEnum;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.InventoryProductEntity;
import com.xbongbong.saas.domain.entity.ext.InventoryEntityExt;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.InventoryEnum;
import com.xbongbong.saas.enums.dictionary.InventoryTypeEnum;
import com.xbongbong.saas.model.InventoryModel;
import com.xbongbong.saas.model.InventoryProductModel;
import com.xbongbong.saas.model.PaasFormSubDataModel;
import com.xbongbong.saas.service.InventoryService;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.UserModel;
import com.xbongbong.workflow.domain.entity.WorkflowBackupDataEntity;
import com.xbongbong.workflow.model.WorkflowBackupDataModel;
import com.xbongbong.workflow.pojo.Data;
import com.xbongbong.workflow.pojo.User;
import com.xbongbong.workflow.pojo.WorkflowTransferPOJO;
import com.xbongbong.workflow.service.strategy.data.AbstractWorkflowDataStrategy;
import com.xbongbong.workflow.service.strategy.data.WorkflowDataProcessStrategy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 *
 * @author 魏荣杰
 *
 */
@Service
@Slf4j
public class WorkflowInventoryStrategy extends AbstractWorkflowDataStrategy implements WorkflowDataProcessStrategy {


    @Resource
    private UserModel userModel;
    @Resource
    private InventoryModel inventoryModel;
    @Resource
    private InventoryService inventoryService;
    @Resource
    private WorkflowBackupDataModel workflowBackupDataModel;
    @Resource
    private InventoryProductModel inventoryProductModel;
    @Resource
    private PaasFormSubDataModel paasFormSubDataModel;

    @Override
    public List<Integer> type() {
        return Collections.singletonList(XbbRefTypeEnum.INVENTORY.getCode());
    }

    @Override
    public void save(WorkflowTransferPOJO workflowTransferPOJO, SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo) throws XbbException {
        // 文件柜
        saveDataCabinetFile(workflowTransferPOJO);

        String corpid = workflowTransferPOJO.getCorpid();
        Data pojoData = workflowTransferPOJO.getData();
        JSONObject data = pojoData.getData();
        Long dataId = pojoData.getId();
        Long formId = pojoData.getFormId();

        User user = workflowTransferPOJO.getUser();
        UserEntity userEntity = userModel.getByKeyIngoreDel(user.getUserId(), corpid);
        UserVO userVO = new UserVO();
        BeanUtil.copyProperties(userEntity, userVO);


        String inventoryType = FastJsonHelper.getStringOrDefaultFromFormData(data, InventoryEnum.INVENTORY_TYPE.getAttr(), InventoryTypeEnum.STANDARD_INVENTORY.getCode());

        if (Objects.equals(inventoryType, InventoryTypeEnum.FAST_INVENTORY.getCode())) {
            InventoryEntityExt inventoryEntityExt = inventoryModel.getByKey(dataId, corpid);
            inventoryEntityExt.setData(data);
            SaasFormSaveDTO saasFormSaveDTO = new SaasFormSaveDTO();
            saasFormSaveDTO.setCorpid(corpid);
            saasFormSaveDTO.setBusinessType(pojoData.getBusinessType());
            saasFormSaveDTO.setOldData(data);
            saasFormSaveDTO.setNewData(data);
            saasFormSaveDTO.setNewPaasFormDataEntity(inventoryEntityExt);
            saasFormSaveDTO.setOldPaasFormDataEntity(inventoryEntityExt);
            saasFormSaveDTO.setIsNew(true);
            saasFormSaveDTO.setIsImport(workflowTransferPOJO.getIsImport());
            saasFormSaveDTO.setLoginUser(userVO);
            saasFormSaveDTO.setUserId(user.getUserId());
            saasFormSaveDTO.setLoginUserName(user.getName());
            saasFormSaveDTO.setPlatform(PlatFormEnum.INTERNAL.getValue());

            inventoryService.generateStockSheet(saasFormSaveDTO);

        }
        addLinkDataDynamic(workflowTransferPOJO);
        // api
        apiHook(workflowTransferPOJO);
        // log
        afterSaveLog(workflowTransferPOJO);
    }

    @Override
    public void update(WorkflowTransferPOJO workflowTransferPOJO, SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo) throws XbbException {
        // 文件柜
        saveDataCabinetFile(workflowTransferPOJO);

        // api
        apiHook(workflowTransferPOJO);
        // log
        afterUpdateLog(workflowTransferPOJO);
    }

    @Override
    public void updateBack(Long taskId, WorkflowTransferPOJO workflowTransferPOJO) throws XbbException {
        try {
            String corpid = workflowTransferPOJO.getCorpid();
            Long backupDataId = workflowTransferPOJO.getBackupDataId();
            Long dataId = workflowTransferPOJO.getData().getId();
            WorkflowBackupDataEntity workflowBackupDataEntity = workflowBackupDataModel.getByKey(backupDataId, corpid);
            if (Objects.nonNull(workflowBackupDataEntity)) {
                JSONObject data = workflowBackupDataEntity.getData();

                replenishAttrForBackupData(workflowTransferPOJO.getData().getData(), data);

                InventoryEntityExt inventoryEntityExt = new InventoryEntityExt();
                inventoryEntityExt.setId(dataId);
                inventoryEntityExt.setCorpid(corpid);
                inventoryEntityExt.setData(data);
                inventoryEntityExt.setSerialNo(data.getString(FieldTypeEnum.SERIALNO.getAlias()));
                // 获取负责人
                inventoryEntityExt.setOwnerId(getOwnerId(data));
                inventoryEntityExt.setDepartmentId(data.getLong(FieldTypeEnum.DEPARTMENTID.getAlias()));
                List<InventoryProductEntity> list = JSON.parseArray(data.getString(StringConstant.PRODUCT), InventoryProductEntity.class);

                FormDataUtil.removeSystemData(data);
                data.remove(StringConstant.PRODUCT);
                if (Objects.equals(workflowTransferPOJO.getOperate(), WorkflowOperateEnum.UPDATE.getType())) {
                    inventoryEntityExt.setFlowStatus(FlowStatusEnum.PASS.getType());
                }
                inventoryModel.update(inventoryEntityExt);
                // 回退被删掉的子表单
                updateBackSubForm(inventoryEntityExt, corpid, IndexTypeEnum.IDX_SAAS_INVENTORY_SUB);
                // 产品
                saveProduct(list, corpid, dataId);
                //回退被删掉的富文本
                updateBackRichText(taskId, workflowTransferPOJO);
            }
        } catch (Exception e) {
            log.error("com.xbongbong.workflow.service.strategy.data.impl.WorkflowInventoryStrategy.updateBack error ", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    @Override
    public void approvalFailed(Long taskId, WorkflowTransferPOJO workflowTransferPOJO, Integer taskType) throws XbbException {
        try {
            String corpid = workflowTransferPOJO.getCorpid();
            Data workflowData = workflowTransferPOJO.getData();
            Long dataId = workflowData.getId();
            Long formId = workflowData.getFormId();
            Integer businessType = workflowData.getBusinessType();
            Integer saasMark = workflowData.getSaasMark();
            InventoryEntityExt inventoryEntityExt = new InventoryEntityExt();
            inventoryEntityExt.setId(dataId);
            if (Objects.equals(TaskTypeEnum.REVOKE.getType(), taskType)) {
                inventoryEntityExt.setFlowStatus(FlowStatusEnum.REVOKE.getType());
            } else {
                inventoryEntityExt.setFlowStatus(FlowStatusEnum.REJECT.getType());
            }
            inventoryEntityExt.setCorpid(corpid);
            inventoryEntityExt.setUpdateTime(DateTimeUtil.getInt());
            inventoryModel.update(inventoryEntityExt);
            // 子表单
            DelEnum del = DelEnum.APPROVE_FAILED;

            paasFormSubDataModel.deleteBatchByDataId(Collections.singletonList(dataId), corpid, IndexTypeEnum.IDX_SAAS_INVENTORY_SUB, del);
            //富文本
            deleteFormRichText(dataId, corpid, formId, businessType, saasMark, DelEnum.NORMAL);

            // 关联产品
            List<InventoryProductEntity> productList = inventoryProductModel.getProductsByInventoryId(dataId, corpid);
            if (CollectionsUtil.isNotEmpty(productList)) {
                List<Long> idIn = new ArrayList<>();
                productList.forEach(item->idIn.add(item.getId()));
                inventoryProductModel.deleteBatch(idIn, corpid, del.getDel());
            }
        } catch (Exception e) {
            log.error("com.xbongbong.workflow.service.strategy.data.impl.WorkflowInventoryStrategy.approvalFailed error ", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    private void saveProduct(List<InventoryProductEntity> list, String corpid, Long dataId) throws XbbException {
        try {
            List<InventoryProductEntity> productList = inventoryProductModel.getProductsByInventoryId(dataId, corpid);

            List<Long> deleteProductId = new ArrayList<>();
            // 遍历备份表中的产品
            List<Long> backupProductId = new ArrayList<>();
            list.forEach(item->backupProductId.add(item.getId()));


            // 移除掉备份表中的产品
            productList.forEach(item->{
                if (!backupProductId.contains(item.getId())) {
                    deleteProductId.add(item.getId());
                }
            });


            if (CollectionsUtil.isNotEmpty(deleteProductId)) {
                inventoryProductModel.deleteBatch(deleteProductId, corpid, DelEnum.DELETE.getDel());
            }
            if (CollectionsUtil.isNotEmpty(list)) {
                inventoryProductModel.updateMulti(list, corpid);
            }


        } catch (Exception e) {
            log.error("com.xbongbong.workflow.service.strategy.data.impl.WorkflowInventoryStrategy.saveProduct error ", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }
}
